using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows.Input;
using KinonekoSoftware.Foundation.Languages;
using KinonekoSoftware.Foundation;
using KinonekoSoftware.Foundation.UI;

namespace KinonekoSoftware.Foundation.UI.ViewModels
{
    public abstract partial class ViewModelBase : ManagedLifetimeObject
    {
        private readonly List<ICommand>               _commands;
        private readonly Dictionary<string, ICommand> _commandDictionary;
        private          bool                         _enableSafetyExit;
        private          string                       _title;
        private          bool                         _isDangerState;
        private          string                       _tempTitle;
        private          string                       _id;
        private          bool                         _immutable;

        protected ViewModelBase()
        {
            _id                = Guid.NewGuid().ToString("N");
            _commands          = new List<ICommand>(8);
            _commandDictionary = new Dictionary<string, ICommand>();
            Commands           = new ReadOnlyCollection<ICommand>(_commands);
            CommandTracker     = new Dictionary<string, ICommand>(_commandDictionary);
            Title              = LanguageManager.GetViewModel(this);
            EnableViewCache    = true;
        }

        internal void SetId(string id)
        {
            if (string.IsNullOrEmpty(id))
                id = _id;

            if (!_immutable)
            {
                _id        = id;
                _immutable = true;
            }
        }

        protected sealed override void SuspendBefore()
        {
            if (!EnableViewCache)
            {
                ViewStateCallback = null;
            }

            base.SuspendBefore();
        }


        protected sealed override void StopAfter()
        {
            Xplat.Debug($"ViewModel : {Id}, 已经清除View层缓存!");
            ViewCache         = null;
            ViewStateCallback = null;
        }

        /// <summary>
        /// 设置数据脏状态
        /// </summary>
        /// <param name="dirtyState">数据脏状态</param>
        public void SetDirtyState(bool dirtyState)
        {
            if (string.IsNullOrEmpty(_tempTitle))
            {
                _tempTitle = _title;
            }

            _title = dirtyState ? $"● {_tempTitle}" : _tempTitle;
            RaiseUpdated(nameof(Title));

            if (EnableSafetyExit)
            {
                IsChange = dirtyState;
            }
        }

        /// <summary>
        /// 设置已删除状态
        /// </summary>
        /// <param name="dirtyState">数据脏状态</param>
        public void SetDeletedState(bool dirtyState)
        {
            SetDirtyState(dirtyState);
            IsDangerState = dirtyState;
        }

        //-------------------------------------------------------------
        //
        //          PushToView
        //
        //-------------------------------------------------------------

        #region PushToView

        /// <summary>
        /// 推送消息，通知View应该更新了
        /// </summary>
        /// <param name="parameter">参数</param>
        public void PushToView(object parameter) => ViewStateCallback?.Invoke(parameter);

        /// <summary>
        /// 推送消息，通知View应该更新了
        /// </summary>
        public void PushToView() => PushToView(null);

        #endregion



        //-------------------------------------------------------------
        //
        //          Dispose
        //
        //-------------------------------------------------------------

        protected IReadOnlyDictionary<string, ICommand> CommandTracker { get; }
        protected IReadOnlyList<ICommand>               Commands       { get; }


        public bool IsDangerState
        {
            get => _isDangerState;
            set => SetValue(ref _isDangerState, value);
        }

        /// <summary>
        /// 获取或设置标题。
        /// </summary>
        public string Title
        {
            get => _title;
            set
            {
                SetValue(ref _title, value);
                _tempTitle = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public string Id => _id;

        /// <summary>
        /// 
        /// </summary>
        public bool IsChange { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        internal Action<object> ViewStateCallback { get; set; }

        /// <summary>
        /// 是否开启安全检查，如果开启安全检查则在退出视图模型时提示用户
        /// </summary>
        public bool EnableSafetyExit
        {
            get => _enableSafetyExit;
            set => SetValue(ref _enableSafetyExit, value);
        }


        /// <summary>
        /// 是否为单例视图模型
        /// </summary>
        /// <remarks>
        /// 单例视图模型在全局中只能存在一个同样类型的。
        /// </remarks>
        public bool IsSingleton { get; protected set; }
    }
}